import tnx from '@/tnx.js';
import TypeKind from '../enums/TypeKind.js';

/**
 * 基本类型
 */
export default class BaseType {

    id = '';
    kind = TypeKind.CLASS;
    packageName = '';
    simpleName = '';
    final = false;

    /**
     * @param kind 性质
     * @param {String} packageName 包名
     * @param {String} simpleName 简名
     */
    constructor(kind, packageName, simpleName) {
        this.kind = TypeKind.validate(kind);
        this.packageName = packageName || '';
        this.simpleName = simpleName;
        this.id = this.getName();
        this.final = this.kind.supports('final');
    }

    static getModuleName(packageName) {
        let packageNameArray = packageName.split('.');
        if (packageNameArray[packageNameArray.length - 1] === 'entity') {
            packageNameArray.pop();
        }
        let moduleName = packageNameArray[packageNameArray.length - 1];
        if (moduleName === 'model') {
            moduleName = undefined;
        }
        return moduleName || '';
    }

    static of(object) {
        if (typeof object !== 'object') {
            return undefined;
        }
        let clazz = new BaseType(object.kind, object.packageName, object.simpleName);
        clazz.update(object);
        return clazz;
    }

    update(object) {
        return tnx.util.object.rewriteSimpleDefined(this, object, 'kind');
    }

    clone() {
        return BaseType.of(this);
    }

    getId() {
        return this.id;
    }

    getKind() {
        return this.kind;
    }

    getName() {
        let name = this.packageName;
        if (name) {
            name += '.';
        }
        return name + this.simpleName;
    }

    isPrimitive() {
        return TypeKind.PRIMITIVE.equals(this.kind);
    }

    isFinal() {
        return this.final;
    }

    matches(object) {
        if (typeof object === 'string') {
            if (object.length === 32 && this.id === object) {
                return true;
            }
            return this.getName() === object;
        }
        if (typeof object === 'object') {
            return this.packageName === object.packageName && this.simpleName === object.simpleName;
        }
        return false;
    }

}
